/* -----------------
* brief
* 1. this is code gen by tools
* 2. mvc code are driver by the model defined with the same filename,
	 for example:
	 there is a Xmodel struct define in xmodel.go file, after the script run (lego model-mvc module_name xmodel)
     it will auto create the code under the module's path
	 m --> xmodel.go
	 v --> view
	 c --> xmodel_ctrl
* 3. you should modify this code if it doesn't satisfy your purpose
*/

package controller

import (
	"encoding/json"
	"errors"
	"github.com/mjiulee/lego"
	"github.com/mjiulee/lego/utils"
	"github.com/valyala/fasthttp"
	"saas_sys_base/common"

	. "saas_sys_base/modules/appmanager/models"
	. "saas_sys_base/modules/appmanager/service"
)

type AppSuitCtrl struct {
	service AppSuitService
	appSuitItemService AppSuitItemService
	tbAppSuit AppSuit
	tbAppSuitItem AppSuitItem
}

func init() {
	vc := new(AppSuitCtrl)
	_ctrlList = append(_ctrlList, vc)
}

func (vc *AppSuitCtrl) CtrlInfo() string {
	return "AppSuitCtrl"
}

func (vc *AppSuitCtrl) RoutInit() {
	// 列表页面
	lego.GET("/admin/appmanager/AppSuit/listpage", vc.ListPage, lego.LEGO_SESSION_TYPE_ADMIN, false)
	lego.GET("/admin/appmanager/AppSuit/listjson", vc.ListJson, lego.LEGO_SESSION_TYPE_ADMIN, false)
	// 编辑页面
	lego.GET("/admin/appmanager/AppSuit/editpage", vc.GetEditPage, lego.LEGO_SESSION_TYPE_ADMIN, false)
	lego.POST("/admin/appmanager/AppSuit/editpage", vc.PostEditPage, lego.LEGO_SESSION_TYPE_ADMIN, false)
	// 删除
	lego.POST("/admin/appmanager/AppSuit/del", vc.DelRecode, lego.LEGO_SESSION_TYPE_ADMIN, false)

	//租户管理端接口
	lego.GET("/admin/appmanager/AppSuit/listpage_saas", vc.ListPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, false)
	lego.GET("/admin/appmanager/AppSuit/listjson_saas", vc.ListJson_Saas, lego.LEGO_SESSION_TYPE_ADMIN, false)

	lego.GET("/admin/appmanager/AppSuit/editpage_saas", vc.GetEditPage_Saas, lego.LEGO_SESSION_TYPE_ADMIN, false)
}

/* 列表接口
* params:
  ---
*/
func (vc *AppSuitCtrl) ListJson(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		//:saas管理端使用代码，使用时将注释解开 sessionData := common.GetSessionData(&ctxExt)
		//:appwho := sessionData.AppTokenWho

		// 表单校验
		type ReqParams struct {
			Keyword string // 关键字查询
			Page    int    `vd:"$>0"` // 分页
			PSize   int    `vd:"$>0"` // 分页大小

			OrderField string
			Order      string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			Keyword:    string(ctxExt.Peek("keyword")),
			Page:       utils.BytesToInt(ctxExt.Peek("page")),
			PSize:      utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField: string(ctxExt.Peek("order_field")),
			Order:      string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		// 业务查询
		if list, total, err := vc.service.ListAppSuit(req.Keyword, req.Page, req.PSize, req.OrderField, req.Order); err != nil {
			code = 100
			msg = "fail"
			lego.LogError(err)
		} else {
			response["count"] = total
			response["data"] = list
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppSuitCtrl) ListPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("appmanager/view/AppSuit/list.html", data)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppSuitCtrl) GetEditPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetAppSuitById(req.Id)
		data["detail"] = target
		break
	}
	ctxExt.HTML("appmanager/view/AppSuit/edit.html", data)
	return
}

/* 数据编辑
* params:
  ---
*/
func (vc *AppSuitCtrl) PostEditPage(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	data := make(map[string]interface{})

	code := 0
	msg := ""

	for {
		//:saas管理端使用代码，使用时将注释解开 sessionData := common.GetSessionData(&ctxExt)
		//:appwho := sessionData.AppTokenWho

		type AppSuitItemDto struct {
			Id        int64  `json:"id,string"`
			IfDel     int `json:"if_del"`
			Cdate     string ` json:"cdate"`
			Udate     string `json:"udate"`
			// add your custom field here
			AppSuitId int64 `json:"app_suit_id,string"`
			AppSuitCode int64 `json:"suit_code"`
			MiniAppId int64 ` json:"mini_app_id"`
			CheckMode    common.CHECK_MODE   ` json:"check_mode"`
		}

		// 表单校验
		type ReqParams struct {
			//#ModelEditFormDefined#
			Id       int64  `vd:"" json:"id,string"`
			IfDel    int    `vd:"" json:"if_del"`
			Cdate    string `vd:"" json:"cdate"`
			Udate    string `vd:"" json:"udate"`
			AppSuitCode int64  `vd:"" json:"suit_code"`
			AppSuitName string `vd:"" json:"suit_name"`
			SortIdx  int    `vd:"" json:"sort_idx"`
			Applist []AppSuitItemDto `vd:"" json:"applist"`
		}

		var req ReqParams

		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, req)
		if err != nil {
			code = 100
			msg = err.Error()
			break
		}

		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		// 业务处理
		recode := vc.service.GetAppSuitById(req.Id)
		if recode == nil {
			// 新建
			recode := new(AppSuit)
			//#ModelFiledMapper#'
			recode.Id = req.Id
			recode.IfDel = req.IfDel
			recode.Cdate = req.Cdate
			recode.Udate = req.Udate
			recode.AppSuitCode = req.AppSuitCode
			recode.AppSuitCode = req.AppSuitCode
			recode.SortIdx = req.SortIdx

			s := lego.NewDBSession()
			s.Begin()
			if false == vc.tbAppSuit.AddRecodeWithsession(s.GetSession(), recode) {
				code = 100
				msg = "false"
				s.Rollback()
				break
			}

			for _, v := range req.Applist{
				appitem := new(AppSuitItem)
				appitem.MiniAppId = v.MiniAppId
				appitem.AppSuitCode = v.AppSuitCode
				appitem.CheckMode = v.CheckMode

				appitem.AppSuitId = recode.Id  //将上面的AppSuit表项id赋值在这里
				appitem.AppSuitCode = recode.AppSuitCode

				if false == vc.tbAppSuitItem.AddRecodeWithsession(s.GetSession(), appitem) {
					code = 100
					msg = "false"
					s.Rollback()
					break
				}
			}
			s.Commit()
		} else {
			//#ModelFiledMapper#
			recode.Id = req.Id
			recode.IfDel = req.IfDel
			recode.Cdate = req.Cdate
			recode.Udate = req.Udate

			recode.AppSuitCode = req.AppSuitCode
			recode.AppSuitCode = req.AppSuitCode
			recode.SortIdx = req.SortIdx

			reqAppList := make([]AppSuitItem, 0)
            for _, v :=range req.Applist {
            	if v.AppSuitId != 0 && v.AppSuitId != req.Id {
            		panic("AppSuitId invalid")
				}

            	item := new(AppSuitItem)
				item.Id = v.Id
				item.AppSuitId = v.AppSuitId
				item.MiniAppId = v.MiniAppId
				item.AppSuitCode = v.AppSuitCode
				item.CheckMode = v.CheckMode
				reqAppList = append(reqAppList, *item)
			}

			dbList, _, err  := vc.appSuitItemService.ListAppSuitItemByAppSuitId(req.Id, 1, 50) //写死最多查询50条
			if err != nil {
				code = 100
				msg = "false"
				break
			}

			utils.UpdateDbList(dbList, reqAppList,
				func(left interface{}, right interface{}) bool {
				    l := left.(AppSuitItem)
					r := right.(AppSuitItem)
					if l.Id == r.Id {
						return true
					}

					return false
			    },
			    //增
				func (old interface{}, new interface{}) error{
					item := new.(AppSuitItem)
					item.AppSuitId = req.Id
					if false == vc.tbAppSuitItem.AddRecode(&item) {
						return errors.New("vc.tbAppSuitItem.AddRecode failed")
					}
					return nil
				},
				//删
				func (old interface{}, new interface{}) error{
					item := old.(AppSuitItem)
					if false == vc.tbAppSuitItem.DelRecodeById(item.Id) {
						return errors.New("vc.tbAppSuitItem.DelRecodeById failed")
					}
					return nil
				},
				//改
				func (old interface{}, new interface{}) error{
					//olditem := old.(AppSuitItem)
					newitem := new.(AppSuitItem)
					if false == vc.tbAppSuitItem.UpdateRecode(&newitem) {
						return errors.New("vc.tbAppSuitItem.UpdateRecode failed")
					}
					return nil
				},
			)

		}
		break
	}
	response["code"] = code
	response["msg"] = msg
	response["data"] = data
	ctxExt.JSON(200, response)
	return
}

/* 删除数据记录
* params:
  ---
*/
func (vc *AppSuitCtrl) DelRecode(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	data := make(map[string]interface{})

	code := 0
	msg := ""
	for {
		// 表单校验
		type ReqParams struct {
			Id int64 `vd:"$>0"` // 记录id
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		// 业务删除
		target := vc.service.GetAppSuitById(req.Id)
		if target == nil {
			code = 100
			msg = "记录不存在"
			break
		}

		if false == vc.service.DelAppSuitById(target.Id) {
			code = 100
			msg = "操作失败"
			break
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	response["data"] = data
	ctxExt.JSON(200, response)
	return
}

//租户管理端 for saas ********
/* 列表接口
* params:
  ---
*/
func (vc *AppSuitCtrl) ListJson_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := ""

	for {
		sessionData := common.GetSessionData(&ctxExt)
		appwho := sessionData.AppTokenWho

		// 表单校验
		type ReqParams struct {
			Keyword string // 关键字查询
			Page    int    `vd:"$>=0"` // 分页
			PSize   int    `vd:"$>0"`  // 分页大小

			OrderField string
			Order      string `vd:"$=='' || $=='asc' || $=='desc'"`
		}
		req := ReqParams{
			Keyword:    string(ctxExt.Peek("keyword")),
			Page:       utils.BytesToInt(ctxExt.Peek("page")),
			PSize:      utils.BytesToInt(ctxExt.Peek("limit")),
			OrderField: string(ctxExt.Peek("order_field")),
			Order:      string(ctxExt.Peek("order")),
		}
		if err := lego.Validate(req); err != nil {
			code = 100
			msg = err.Error()
			break
		}

		// 业务查询
		if list, total, err := vc.service.ListAppSuitByWho(appwho, req.Keyword, req.Page, req.PSize, req.OrderField, req.Order); err != nil {
			lego.LogError(err)
		} else {
			response["count"] = total
			response["data"] = list
		}
		break
	}

	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppSuitCtrl) ListPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量
		break
	}
	ctxExt.HTML("appmanager/view/AppSuit/list_saas.html", data)
	return
}

/* 添加数据记录
* params:
  ---
*/
func (vc *AppSuitCtrl) GetEditPage_Saas(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	data := make(map[string]interface{})
	for {
		sessionData := common.GetSessionData(&ctxExt) //
		appwho := sessionData.AppTokenWho
		data["Who"] = appwho //adminSaas(租户管理端)使用的变量

		type ReqParams struct {
			Id int64 // 记录id，为空则新建，否则为编辑
		}
		req := ReqParams{
			Id: utils.BytesToInt64(ctxExt.Peek("id")),
		}
		if err := lego.Validate(req); err != nil {
			break
		}
		target := vc.service.GetAppSuitById(req.Id)
		applist, _, _ := vc.appSuitItemService.ListAppSuitItemByAppSuitId(target.Id, 1, 100) //写死100
		data["detail"] = target
		data["applist"] = applist
		break
	}
	ctxExt.HTML("appmanager/view/AppSuit/edit_saas.html", data)
	return
}

